#include"touch.h"
#include"lcd.h"
#include"bmp.h"
BMP *bmp_init(const char *bmpname)
{
	// 打开BMP
	int bmp_fd = open(bmpname, O_RDONLY);
	if(bmp_fd < 0) {
		perror("open BMP fail");
		return NULL;
	}
	
	BMP *bmp = calloc(1, sizeof(BMP));
	if(bmp == NULL)
	{
		perror("bmp_init calloc fail");
		return NULL;
	}
	
	// 读取BMP格式头，获取图片信息
	struct bitmap_header header;
	struct bitmap_info info;
	
	// 第一、二个结构体是必有信息
	read(bmp_fd, &header, sizeof(header));
	read(bmp_fd, &info, sizeof(info));
	
	// BMP的像素宽高，位深度
	bmp->width = info.width;
	bmp->height = info.height;
	bmp->bpp = info.bit_count;
	bmp->size = info.size_img;
	
	// 一行像素字节数，不含pad
	bmp->row_size = bmp->width * bmp->bpp/8;
	
	// 读BMP图像数据
	bmp->rgb = calloc(1, bmp->size);	
	if(bmp->rgb == NULL)
	{
		perror("rgb 缓存区申请失败\n");
		return NULL;
	}
		
	read(bmp_fd, bmp->rgb, bmp->size);

	// 计算无效字节数
    bmp->pad = ((4-( bmp->width * bmp->bpp/8 ) % 4)) % 4;
	
	close(bmp_fd);
	
	return bmp;
}

void bmp_uninit(BMP *bmp)
{
	free(bmp->rgb);
	free(bmp);
}

// 显示图片
// 获取BMP的信息（像素宽高，位深度，图像数据大小，图像数据）
// 把图像数据拷贝到LCD显存
// 释放资源
void anybmp(int xoff, int yoff, const char *bmpname, LCD *lcd)
{
	// 获取bmp信息
	BMP *bmp = bmp_init(bmpname);
	
	char *rgb = bmp->rgb;
	
	// 让rgb指向最末一行的首字节
	rgb += (bmp->width * bmp->bpp/8 + bmp->pad) * (bmp->height - 1);

	int x, y;
	for(y=0; y<lcd->height && y<bmp->height; y++)
	{
			// 显示一行
		for(x=0; x<lcd->width && x<bmp->width; x++)
		{
			int lcd_offset = (lcd->width*(y+yoff) + (x+xoff))*4;
			// 将一个像素点从图片复制到显存
			memcpy(lcd->fbmem+lcd_offset, rgb, bmp->bpp/8);
			rgb += bmp->bpp/8;
		}
		// 显示完一行之后，跳过pad个无效字节
		rgb += bmp->pad;
		// 让rgb指向上一行行首
		rgb -= (bmp->width * bmp->bpp/8 + bmp->pad) * 2;	
	} 
	
	// 释放bmp资源
	bmp_uninit(bmp);
}